package com.gzhryc.shared_device.oem.code.statistics.services;

import com.gzhryc.common.DateTools;
import com.gzhryc.common.logging.Logger;
import com.gzhryc.jdbc.Conditions;
import com.gzhryc.jdbc.MultiDBTools;
import com.gzhryc.shared_device.oem.code.statistics.dao.UserProfitDayStatisticsDao;
import com.gzhryc.shared_device.oem.code.statistics.dao.db.UserProfitDayStatistics;
import com.gzhryc.shared_device.oem.code.statistics.dao.models.UserProfitSumMoneyData;
import com.gzhryc.shared_device.oem.code.statistics.services.dao.UserProfitDayStatisticsSearch;
import org.apache.commons.lang3.time.DateFormatUtils;

import java.sql.SQLException;
import java.util.Date;
import java.util.List;

public class UserProfitDayStatisticsService {

    static Logger log = Logger.getLogger(UserProfitDayStatisticsService.class);

    public static UserProfitDayStatisticsService self() {
        return MultiDBTools.getService(UserProfitDayStatisticsService.class, new Date());
    }

    public static UserProfitDayStatisticsService self(Date date) {
        return MultiDBTools.getService(UserProfitDayStatisticsService.class, date);
    }

    UserProfitDayStatisticsDao dao;

    public UserProfitDayStatisticsService(String jdbcKey,Date date) {
        dao = new UserProfitDayStatisticsDao(jdbcKey,date);
    }

    public List<UserProfitDayStatistics> findBySearch(UserProfitDayStatisticsSearch search, Integer pageNo, Integer pageLimit){
        Conditions conditions = dao.buildConditions(search);
        conditions.and().ge("createDate",search.getStartDate());
        conditions.and().le("createDate",search.getEndDate());
        conditions.desc("createDate");
        try {
            return dao.findByCondition(conditions,pageNo,pageLimit);
        } catch (SQLException e) {
            log.error(e.getMessage(),e);
        }
        return null;
    }

    public Long countBySearch(UserProfitDayStatisticsSearch search){
        Conditions conditions = dao.buildConditions(search);
        conditions.and().ge("createDate",search.getStartDate());
        conditions.and().le("createDate",search.getEndDate());
        try {
            return dao.count(conditions);
        } catch (SQLException e) {
            log.error(e.getMessage(),e);
        }
        return 0L;
    }

    public List<UserProfitSumMoneyData> sumGroupUserIdByYear(Integer yearNum, List<Long> userIds){
        if(yearNum != null && userIds != null && userIds.size() > 0) {
            Conditions conditions = new Conditions(UserProfitDayStatistics.class);
            conditions.and().is("yearNum", yearNum);
            conditions.and().in("userId", userIds);
            try {
                return dao.sumGroupUserIdByConditions(conditions);
            } catch (SQLException e) {
                log.error(e.getMessage(), e);
            }
        }
        return null;
    }

    public List<UserProfitSumMoneyData> sumGroupUserIdByYearAndMonth(Integer yearNum,Integer monthNum,List<Long> userIds){
        if(yearNum != null && monthNum != null && userIds != null && userIds.size() > 0) {
            Conditions conditions = new Conditions(UserProfitDayStatistics.class);
            conditions.and().is("yearNum",yearNum);
            conditions.and().is("monthNum",monthNum);
            conditions.and().in("userId", userIds);
            try {
                return dao.sumGroupUserIdByConditions(conditions);
            } catch (SQLException e) {
                log.error(e.getMessage(), e);
            }
        }
        return null;
    }

    public UserProfitDayStatistics getOrAddByKeys(Long userId, String userName,String userPhone,Date createDate) {
        if (userId != null && createDate != null) {
            String dayDate = DateFormatUtils.format(createDate, "yyyyMMdd");
            Conditions conditions = new Conditions(UserProfitDayStatistics.class);
            conditions.and().is("userId", userId);
            conditions.and().is("dayDate", dayDate);
            try {
                UserProfitDayStatistics statistics = dao.get(conditions);
                if (statistics != null) {
                    return statistics;
                }else{
                    Integer yearNum = Integer.valueOf(DateFormatUtils.format(createDate, "yyyy"));
                    Integer monthNum = Integer.valueOf(DateFormatUtils.format(createDate, "MM"));
                    Integer dayNum = Integer.valueOf(DateFormatUtils.format(createDate, "dd"));
                    statistics = new UserProfitDayStatistics();
                    statistics.setUserId(userId);
                    statistics.setUserName(userName);
                    statistics.setUserPhone(userPhone);
                    statistics.setDayDate(dayDate);
                    statistics.setYearNum(yearNum);
                    statistics.setMonthNum(monthNum);
                    statistics.setDayNum(dayNum);
                    statistics.setCreateDate(createDate);

                    if (dao.insert(statistics) > 0) {
                        return statistics;
                    }
                }
            } catch (SQLException e) {
                log.error(e.getMessage(), e);
            }
        }
        return null;
    }

    public UserProfitDayStatistics getByKeys(Long userId,Date date){
        if (userId != null && date != null) {
            String dayDate = DateFormatUtils.format(date, "yyyyMMdd");
            Conditions conditions = new Conditions(UserProfitDayStatistics.class);
            conditions.and().is("userId", userId);
            conditions.and().is("dayDate", dayDate);

            try {
                return dao.get(conditions);
            } catch (SQLException e) {
                log.error(e.getMessage(),e);
            }
        }
        return null;
    }

    public UserProfitSumMoneyData sumByUserAndDate(Long userId,Date startDate,Date endDate){
        if(userId != null && startDate != null && endDate != null){
            Conditions conditions = new Conditions(UserProfitDayStatistics.class);
            conditions.and().is("userId",userId);
            conditions.and().ge("createDate",startDate);
            conditions.and().le("createDate",endDate);

            try {
                return dao.sumMoneyData(conditions);
            } catch (SQLException e) {
                log.error(e.getMessage(),e);
            }
        }
        return null;
    }

    public UserProfitSumMoneyData sumByUserAndMonth(Long userId,Date date){
        if(userId != null && date != null){
            Integer yearNum = Integer.valueOf(DateFormatUtils.format(date, "yyyy"));
            Integer monthNum = Integer.valueOf(DateFormatUtils.format(date, "MM"));

            Conditions conditions = new Conditions(UserProfitDayStatistics.class);
            conditions.and().is("userId",userId);
            conditions.and().is("yearNum",yearNum);
            conditions.and().is("monthNum",monthNum);

            try {
                return dao.sumMoneyData(conditions);
            } catch (SQLException e) {
                log.error(e.getMessage(),e);
            }
        }
        return null;
    }

    public UserProfitSumMoneyData sumByUser(Long userId){
        if(userId != null){
            Conditions conditions = new Conditions(UserProfitDayStatistics.class);
            conditions.and().is("userId",userId);

            try {
                return dao.sumMoneyData(conditions);
            } catch (SQLException e) {
                log.error(e.getMessage(),e);
            }
        }
        return null;
    }

    public void addOneIncomeData(Long userId,String userName,String userPhone,Date divideDate, Long orderMoney, Long incomeMoney,Long refundMoney,Date refundDate) {
        UserProfitDayStatistics statistics = getOrAddByKeys(userId, userName,userPhone,divideDate);
        if (statistics != null) {
            Conditions conditions = new Conditions(UserProfitDayStatistics.class);
            conditions.and().is("userId", userId);
            conditions.and().is("dayDate", statistics.getDayDate());

            if(refundMoney != null && refundDate != null){
                if(DateTools.isSameDay(divideDate,refundDate)) {
                    UserProfitDayStatistics updateEntity = new UserProfitDayStatistics();
                    updateEntity.setIncomeCount(1);
                    updateEntity.setIncomeMoney(incomeMoney);

                    try {
                        if (dao.updateNotNullAndInc(updateEntity, conditions, "incomeCount", "incomeMoney") > 0) {
                            updateEntity = new UserProfitDayStatistics();
                            updateEntity.setRefundCount(1);
                            updateEntity.setRefundMoney(refundMoney);
                            dao.updateNotNullAndReduce(updateEntity, conditions, "refundCount", "refundMoney");
                        }else{
                            log.error("修改用户收益统计(分成)失败，用户：{{0}}，时间：{{1}}", userId, divideDate);
                        }
                    } catch (SQLException e) {
                        log.error(e.getMessage(), e);
                    }
                }else {
                    UserProfitDayStatistics updateEntity = new UserProfitDayStatistics();
                    updateEntity.setIncomeCount(1);
                    updateEntity.setIncomeMoney(incomeMoney);

                    try {
                        if (dao.updateNotNullAndInc(updateEntity, conditions, "incomeCount", "incomeMoney") <= 0) {
                            log.error("修改用户收益统计(历史分成)失败，用户：{{0}}，时间：{{1}}", userId, divideDate);
                        }
                    } catch (SQLException e) {
                        log.error(e.getMessage(), e);
                    }
                }
            }else {
                UserProfitDayStatistics updateEntity = new UserProfitDayStatistics();
                updateEntity.setOrderMoney(orderMoney);
                updateEntity.setIncomeCount(1);
                updateEntity.setIncomeMoney(incomeMoney);

                try {
                    if (dao.updateNotNullAndInc(updateEntity, conditions, "orderMoney", "incomeCount", "incomeMoney") <= 0) {
                        log.error("修改用户收益统计(分成)失败，用户：{{0}}，时间：{{1}}", userId, divideDate);
                    }
                } catch (SQLException e) {
                    log.error(e.getMessage(), e);
                }
            }
        } else {
            log.error("未找到或创建用户收益统计，用户：{{0}}，时间：{{1}}", userId, divideDate);
        }
    }

    public void addOneRefundData(Long userId,String userName,String userPhone,Date refundDate,Long refundMoney,Date divideDate){
        UserProfitDayStatistics statistics = getOrAddByKeys(userId, userName,userPhone,refundDate);
        if (statistics != null) {
            Conditions conditions = new Conditions(UserProfitDayStatistics.class);
            conditions.and().is("userId", userId);
            conditions.and().is("dayDate", statistics.getDayDate());

            if (DateTools.isSameDay(refundDate, divideDate)) {
                UserProfitDayStatistics updateEntity = new UserProfitDayStatistics();
                updateEntity.setRefundCount(1);
                updateEntity.setRefundMoney(refundMoney);

                try {
                    if (dao.updateNotNullAndInc(updateEntity, conditions, "refundCount", "refundMoney") > 0) {
                        updateEntity = new UserProfitDayStatistics();
                        updateEntity.setIncomeCount(1);
                        updateEntity.setIncomeMoney(refundMoney);
                        dao.updateNotNullAndReduce(updateEntity, conditions, "incomeCount", "incomeCount");
                    }else{
                        log.error("修改用户收益统计(退款)失败，用户：{{0}}，时间：{{1}}", userId, refundDate);
                    }
                } catch (SQLException e) {
                    log.error(e.getMessage(), e);
                }
            }else{
                UserProfitDayStatistics updateEntity = new UserProfitDayStatistics();
                updateEntity.setHistoryRefundCount(1);
                updateEntity.setHistoryRefundMoney(refundMoney);

                try {
                    if (dao.updateNotNullAndInc(updateEntity, conditions, "historyRefundCount", "historyRefundMoney") <= 0) {
                        log.error("修改用户收益统计(历史退款)失败，用户：{{0}}，时间：{{1}}", userId, refundDate);
                    }
                } catch (SQLException e) {
                    log.error(e.getMessage(), e);
                }
            }
        }else {
            log.error("未找到或创建用户收益统计，用户：{{0}}，时间：{{1}}", userId, refundDate);
        }
    }
}
